import pgzrun
from vec import *
import random
import time

WIDTH = 600
HEIGHT = 440

BACK_COLOR = (0, 0, 0)

lastTime = time.time()
deltaTime = 0

rcHeight = [100, 200, 120, 80, 50, 150, 20, 160, 90, 130]
n = len(rcHeight)
rcWidth = 20
space = 10
pspd = 2

class MyRect:
    def __init__(self, lb_x, lb_y, h, clr):
        self.pos = Vec2(lb_x, lb_y)
        self.h = h
        self.clr = clr
        self.p = 0.0
        self.curState = 0   # 0: 静止，1: 移动
        self.start_pt = Vec2(0, 0)
        self.end_pt = Vec2(0, 0)

    def StartMove(self, end_pt):
        if self.curState == 1:
            return

        self.curState = 1
        self.p = 0
        self.start_pt = self.pos
        self.end_pt = end_pt

    def Move(self):
        has_finished = False

        self.p += pspd * deltaTime

        if self.p > 1.0:    
            self.p = 1.0
            has_finished = True

        self.pos = self.start_pt * (1 - self.p) + self.end_pt * self.p

        return has_finished

    def Update(self):
        if self.curState == 1:
            if self.Move() == True:
                self.curState = 0

    def Draw(self):
        rc = Rect((self.pos.x, self.pos.y - self.h), (rcWidth, self.h))
        screen.draw.filled_rect(rc, self.clr)

startX = 150
iter = startX
rcList = []

isSortingFinished = False
sortingState = 0 # 0: 交换数据，1: 移动矩形

room=1
i=0
last_merge=False
if len(rcHeight)//2==1:
    last_merge=True

for item in rcHeight:
    r = 150-item*0.7
    g = 175-item*0.7
    b = 175-item*0.7
    rcList.append(MyRect(iter, HEIGHT / 4*3, item, (r, g, b)))
    iter += rcWidth
    iter += space

def merge(left,right):
    l,r=0,0
    result=[]
    while l<len(left) and r<len(right):
        if left[l]<right[r]:
            result.append(left[l])
            l+=1
        else:
            result.append(right[r])
            r+=1
    result+=list(left[l:])
    result+=list(right[r:])
    return result

def swap(a,b):
    global rcHeight, rcList
    rcList[a].StartMove(rcList[b].pos)
    rcList[b].StartMove(rcList[a].pos)
    rcHeight[a], rcHeight[b] = rcHeight[b], rcHeight[a]
    rcList[a], rcList[b] = rcList[b], rcList[a]
    
def update():
    global lastTime, deltaTime, isSortingFinished, sortingState, i,rcList,room
    curTime = time.time()
    deltaTime = curTime - lastTime
    lastTime = curTime

    if isSortingFinished == True:
        return

    if sortingState == 0:
        if room>=len(rcHeight):
            isSortingFinished=True
        if(last_merge or i<len(rcHeight)//room):
            i+=1
            left=rcHeight[i:(i+1)*room-1]
            right=rcHeight[(i+1)*room:(i+2)*room]
            a=merge(left,right)
            if i*room+last_merge==len(rcHeight):
                i=0
                room*=2
        else:
            a=[rcHeight[-1]]
            i=0
            room*=2
        for j in range(len(a)-1):
            here=rcHeight.index(a[j])
            d=i-1
            if i==0:
                d=len(rcHeight)-1
            go=d*room+j
            swap(here,go)

    else:
        allStoped = True
        for rc  in rcList:
            rc.Update()
            if rc.curState == 1:
                allStoped = False

        if allStoped == True:
            sortingState = 0

def draw():
    screen.clear()
    screen.fill(BACK_COLOR)
    for rc in rcList:
        rc.Draw()

pgzrun.go()